package com.ynu.yx.chatroleai.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.ynu.yx.chatroleai.converter.AICharacterConverter;
import com.ynu.yx.chatroleai.dao.AICharacterDao;
import com.ynu.yx.chatroleai.dao.CharacterCategoryDao;
import com.ynu.yx.chatroleai.dto.AICharacterCreateDto;
import com.ynu.yx.chatroleai.dto.AICharacterUpdateDto;
import com.ynu.yx.chatroleai.model.AICharacter;
import com.ynu.yx.chatroleai.model.CharacterCategory;
import com.ynu.yx.chatroleai.utils.GetNullPropertyNames;
import com.ynu.yx.chatroleai.utils.IdGenerator;
import com.ynu.yx.chatroleai.utils.MsgOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.beans.PropertyDescriptor;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Service
@Slf4j
public class AICharacterService {
    @Resource
    private AICharacterDao aiCharacterDao;
    @Resource
    private AICharacterConverter aiCharacterConverter;
    @Resource
    private GetNullPropertyNames getNullPropertyNames;
    @Resource
    private CharacterCategoryDao characterCategoryDao;
    @Resource
    private IdGenerator idGenerator;

    // ------------------------------- 辅助方法 ---------------------------------


    // ------------------------------- 增 ---------------------------------
    // 创建AI角色
    public MsgOperation createAICharacter(AICharacterCreateDto characterDto) {
        if (characterDto.getName() == null || characterDto.getName().isEmpty()) {
            return new MsgOperation("-1", "角色名称不能为空");
        }
        if (characterDto.getCategoryId() == null) {
            return new MsgOperation("-2", "角色所属类别不能为空");
        }
        if (characterDto.getSystemPrompt() == null || characterDto.getSystemPrompt().isEmpty()) {
            return new MsgOperation("-3", "角色系统提示不能为空");
        }
        if (characterDto.getVoiceStyle() == null || characterDto.getVoiceStyle().isEmpty() || characterDto.getVoiceStyle().length() < 3) {
            return new MsgOperation("-4", "角色语音风格不能为空");
        }
        if  (characterDto.getTtsVoiceId() == null || characterDto.getTtsVoiceId().isEmpty()) {
            return new MsgOperation("-5", "角色文本转语音的语音ID不能为空");
        }
        if (characterDto.getDescription() == null || characterDto.getDescription().isEmpty() || characterDto.getDescription().length() < 3) {
            return  new MsgOperation("-6", "角色描述为空或长度小于3");
        }

        if (characterDto.getPopularity() == null) {
            characterDto.setPopularity(0);
        }
        if (characterDto.getIsActive() == null) {
            characterDto.setIsActive(true);
        }
        if (characterDto.getIsDeleted() == null) {
            characterDto.setIsDeleted(0);
        }

        if (aiCharacterDao.selectOneByName(characterDto.getName()) != null) {
            return new MsgOperation("-7", "角色名称已存在");
        }

        AICharacter aiCharacter = aiCharacterConverter.toModel(characterDto);

        try{
            aiCharacter.setAiId(idGenerator.generateUniqueId(aiCharacterDao, "ai_id"));
        }  catch (Exception e) {
            log.error("生成AI角色ID失败", e);
            return new MsgOperation("-8", "生成AI角色ID失败");
        }

        // 将角色绑定到类别
        QueryWrapper<CharacterCategory> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("category_id", characterDto.getCategoryId());
        CharacterCategory characterCategory = characterCategoryDao.selectOne(queryWrapper);
        if (characterCategory == null) {
            return new MsgOperation("-9", "角色所属类别不存在");
        }
        UpdateWrapper<CharacterCategory> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("category_id", characterDto.getCategoryId());
        updateWrapper.set("ai_id", aiCharacter.getAiId());
        int rows = characterCategoryDao.update(null, updateWrapper);
        if (rows != 1) {
            return new MsgOperation("-10", "绑定角色到类别失败");
        }

        aiCharacterDao.insert(aiCharacter);
        return new MsgOperation("1", "创建角色成功");
    }


    // ------------------------------- 查 ---------------------------------
    // 通过AI角色ID精确查询
    public AICharacter findByAICategoryId(Long aiCategoryId) {
        QueryWrapper<AICharacter> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("ai_id", aiCategoryId);
        return aiCharacterDao.selectOne(queryWrapper);
    }

    // 通过名称模糊查询
    public List<AICharacter> findByNameLike(String name) {
        QueryWrapper<AICharacter> queryWrapper = new QueryWrapper<>();
        queryWrapper.like("name", name);
        return aiCharacterDao.selectList(queryWrapper);
    }

    // 通过分类ID查询
    public List<AICharacter> findByCategoryId(Long categoryId) {
        QueryWrapper<AICharacter> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("category_id", categoryId);
        return aiCharacterDao.selectList(queryWrapper);
    }


    // ------------------------------- 改 ---------------------------------
    // 更新角色信息-通过角色名称
    public MsgOperation updateAICharacterByName(String name, AICharacterUpdateDto aiCharacterUpdateDto) {
        if (name == null || name.isEmpty()) {
            return new MsgOperation("-1", "角色名字不能为空");
        }
        AICharacter aiCharacter = aiCharacterDao.selectOneByName(name);

        if (aiCharacter == null) {
            return new MsgOperation("-2", "角色不存在");
        }

        // 创建要更新的实体
        AICharacter updateCharacter = aiCharacterConverter.toModelFromUpdateDto(aiCharacterUpdateDto);
        // 创建更新条件，根据角色名更新
        UpdateWrapper<AICharacter> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("name", name);

        // 执行更新操作
        int rows = aiCharacterDao.update(updateCharacter, updateWrapper);
        // 根据更新结果返回相应信息
        if (rows > 0) {
            return new MsgOperation("1", "更新角色成功");
        } else {
            return new MsgOperation("-3", "更新角色失败");
        }
    }

    // 更新角色信息-通过角色ID
    public MsgOperation updateAICharacterByAiId(Long AiId, AICharacterUpdateDto aiCharacterUpdateDto) {
        if (AiId == null) {
            return new MsgOperation("-1", "角色名字不能为空");
        }
        AICharacter aiCharacter = aiCharacterDao.selectOneByAiId(AiId);
        if (aiCharacter == null) {
            return new MsgOperation("-2", "角色不存在");
        }
        // 创建要更新的实体
        AICharacter updateCharacter = aiCharacterConverter.toModelFromUpdateDto(aiCharacterUpdateDto);
        // 创建更新条件，根据角色名更新
        UpdateWrapper<AICharacter> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("ai_id", AiId);

        // 执行更新操作
        int rows = aiCharacterDao.update(updateCharacter, updateWrapper);

        // 根据更新结果返回相应信息
        if (rows > 0) {
            return new MsgOperation("1", "更新角色成功");
        } else {
            return new MsgOperation("-3", "更新角色失败");
        }
    }

    // 更改角色所属类别ID，categoryId
    public MsgOperation updateAICharacterCategory(Long AiId, Long categoryId) {
        if (AiId == null) {
            return new MsgOperation("-1", "角色ID不能为空");
        }
        if (categoryId == null) {
            return new MsgOperation("-2", "角色所属类别不能为空");
        }
        AICharacter aiCharacter = aiCharacterDao.selectOneByAiId(AiId);
        if (aiCharacter == null) {
            return new MsgOperation("-3", "角色不存在");
        }
        // 创建更新条件，根据角色名更新
        UpdateWrapper<AICharacter> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("ai_id", AiId);
        // 更新角色所属类别ID
        updateWrapper.set("category_id", categoryId);

        // 移除角色所属类别的AI角色ID
        UpdateWrapper<CharacterCategory> updateCategoryWrapper = new UpdateWrapper<>();
        updateCategoryWrapper.eq("category_id", categoryId).eq("ai_id", AiId).set("ai_id", null);
        if ((characterCategoryDao.update(null, updateCategoryWrapper) <= 0 )){
            return new MsgOperation("-4", "移除角色所属类别的AI角色ID失败");
        }

        // 执行更新操作
        int rows = aiCharacterDao.update(null, updateWrapper);
        // 根据更新结果返回相应信息
        if (rows > 0) {
            return new MsgOperation("1", "更新角色所属类别成功");
        } else {
            return new MsgOperation("-4", "更新角色所属类别失败");
        }
    }

    // ------------------------------- 删 --------------------------------
    // 通过角色名称删除(逻辑删除)
    public MsgOperation deleteByName(String name) {
        if (name == null || name.isEmpty()) {
            return new MsgOperation("-1", "角色名字不能为空");
        }
        AICharacter aiCharacter = aiCharacterDao.selectOneByName(name);
        if (aiCharacter == null) {
            return new MsgOperation("-2", "角色不存在");
        }
        UpdateWrapper<AICharacter> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("name", name).set("is_deleted", 1);
        aiCharacterDao.update(null, updateWrapper);
        return new MsgOperation("1", "删除角色成功");
    }

    // 通过角色ID删除(逻辑删除)
    public MsgOperation deleteByAiId(Long AiId) {
        if (AiId == null) {
            return new MsgOperation("-1", "角色ID不能为空");
        }
        AICharacter aiCharacter = aiCharacterDao.selectOneByAiId(AiId);
        if (aiCharacter == null) {
            return new MsgOperation("-2", "角色不存在");
        }

        UpdateWrapper<AICharacter> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("ai_id", AiId).set("is_deleted", 1);
        aiCharacterDao.update(null, updateWrapper);
        return new MsgOperation("1", "删除角色成功");
    }

    // 通过角色ID删除(逻辑删除)
    public MsgOperation deleteByCategoryId(Long categoryId) {
        if (categoryId == null) {
            return new MsgOperation("-1", "角色分类ID不能为空");
        }
        AICharacter aiCharacter = aiCharacterDao.selectOneByAiId(categoryId);
        if (aiCharacter == null) {
            return new MsgOperation("-2", "角色不存在");
        }

        UpdateWrapper<AICharacter> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("category_id", categoryId).set("is_deleted", 1);
        aiCharacterDao.update(null, updateWrapper);
        return new MsgOperation("1", "删除分类下所有角色成功");
    }
}
